home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / xgopher.1.3 / status.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-25  |  12.4 KB  |  563 lines

  1. /* status.c 
  2.    create and manage status panel. */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19.  
  20. #include <stdio.h>
  21.  
  22. #include <X11/Intrinsic.h>
  23. #include <X11/StringDefs.h>
  24.  
  25. #include <X11/Shell.h>
  26. #include <X11/Xaw/Command.h>
  27. #include <X11/Xaw/Form.h>
  28.  
  29. #include "osdep.h"
  30. #include "xglobals.h"
  31. #include "gui.h"
  32. #include "appres.h"
  33.  
  34. static statusType    type;
  35. static Boolean        cancelled;
  36.  
  37. #define POPUP_SHOW_TIME    5000    /* milliseconds */
  38. #define MSG_SHOW_TIME    2000    /* milliseconds */
  39.  
  40. static Widget        topLevel;
  41. static Widget        statusShell;
  42. static Boolean        statusPanelCreated = False;
  43. Widget            cancelButton;
  44. static Widget        whatLabel, statusLabel1, statusLabel2;
  45. static Boolean        statusUp=False;
  46.  
  47. #define THIS_POPUP_NAME        "statusPopup"
  48.  
  49.                 /* default values */
  50. static popupPosResources    placement = {
  51.  
  52.     /* position centered on the main panel */
  53.     from_main, 50, 50, justify_center, justify_center, True, True
  54.     };
  55.  
  56.  
  57.  
  58. #define STATUS_SHELL_TITLE    "Xgopher Status"
  59. #define TRANSIENT_MESSAGE    "This message will go away shortly!"
  60.  
  61.  
  62. /* cancelProc
  63.    Handle cancel button on the status panel. */
  64.  
  65. static void
  66. cancelProc(w, client_data, call_data)
  67. Widget          w;
  68. XtPointer       client_data, call_data;
  69. {
  70.         cancelled = True;
  71.         return;
  72. }
  73.  
  74.  
  75. /* statusCancelAction
  76.    Indicate the user has elected to cancel the operation. */
  77.  
  78. static void
  79. statusCancelAction(w, event, parms, nparms)
  80. Widget          w;
  81. XEvent          *event;
  82. String          *parms;
  83. Cardinal        *nparms;
  84. {
  85.         cancelProc(w, NULL, NULL);
  86.         return;
  87. }
  88.  
  89.  
  90. /* timeToRemoveProc
  91.    remove a temporary status panel when the timer goes off */
  92.  
  93. static void
  94. timeToRemoveProc(clientData, id)
  95. XtPointer    clientData;
  96. XtIntervalId    *id;
  97. {
  98.     removeStatusPanel();
  99. }
  100.  
  101.  
  102. /* displayStatusPanel
  103.    display the status info panel */
  104.  
  105. void
  106. displayStatusPanel(thisType, text, host, port)
  107. statusType    thisType;
  108. char        *text;
  109. char        *host;
  110. int        port;
  111. {
  112.  
  113.  
  114.     Arg        args[10];
  115.     Cardinal    n;
  116.     char    message[MESSAGE_STRING_LEN];
  117.  
  118.     if (appResources->statusWindow) {    /* STATUS_POPUP */
  119.  
  120.     if (! statusPanelCreated) return;
  121.  
  122.     /* In case the status panel is already up,
  123.        drain all events to see any cancel from 
  124.        before. */
  125.  
  126.     if (statusUp) { 
  127.         WaitForAllPendingEventsAndExpose(
  128.             XtDisplay(statusShell),
  129.             (Window) NULL );
  130.     } else {
  131.         cancelled = False;
  132.     }
  133.  
  134.     type = thisType;
  135.  
  136.     /* set status fields */
  137.  
  138.     n=0;
  139.     XtSetArg(args[n], XtNlabel, text);  n++;
  140.     XtSetValues(whatLabel, args, n);
  141.  
  142.     switch (type) {
  143.     case STAT_CONNECT:
  144.         sprintf (message, "%s, port %d", host, port);
  145.         n=0;
  146.         XtSetArg(args[n], XtNlabel, message);  n++;
  147.         XtSetValues(statusLabel1, args, n);
  148.  
  149.         n=0;
  150.         XtSetArg(args[n], XtNlabel,
  151.                 "(This may take some time)");  n++;
  152.         XtSetValues(statusLabel2, args, n);
  153.  
  154.         XtUnmanageChild(cancelButton);
  155.  
  156.         break;
  157.     case STAT_ROOT:
  158.     case STAT_DIRECTORY:
  159.         sprintf (message, "Waiting for data to start arriving", 0);
  160.         n=0;
  161.         XtSetArg(args[n], XtNlabel, message);  n++;
  162.         XtSetValues(statusLabel1, args, n);
  163.  
  164.         n=0;
  165.         XtSetArg(args[n], XtNlabel, " "); n++;
  166.         XtSetValues(statusLabel2, args, n);
  167.  
  168.         if (type == STAT_ROOT) {
  169.             XtUnmanageChild(cancelButton);
  170.         }else {
  171.             XtManageChild(cancelButton);
  172.         }
  173.  
  174.         break;
  175.     case STAT_ASCII:
  176.         sprintf (message, "Waiting for data to start arriving");
  177.         n=0;
  178.         XtSetArg(args[n], XtNlabel, message);  n++;
  179.         XtSetValues(statusLabel1, args, n);
  180.  
  181.         n=0;
  182.         XtSetArg(args[n], XtNlabel, " "); n++;
  183.         XtSetValues(statusLabel2, args, n);
  184.  
  185.         XtManageChild(cancelButton);
  186.  
  187.         break;
  188.     case STAT_BINARY:
  189.         sprintf (message, "Waiting for data to start arriving");
  190.         n=0;
  191.         XtSetArg(args[n], XtNlabel, message);  n++;
  192.         XtSetValues(statusLabel1, args, n);
  193.  
  194.         n=0;
  195.         XtSetArg(args[n], XtNlabel, " "); n++;
  196.         XtSetValues(statusLabel2, args, n);
  197.  
  198.         XtManageChild(cancelButton);
  199.  
  200.         break;
  201.     case STAT_PROCESS:
  202.         n=0;
  203.         XtSetArg(args[n], XtNlabel, " ");  n++;
  204.         XtSetValues(statusLabel1, args, n);
  205.  
  206.         n=0;
  207.         XtSetArg(args[n], XtNlabel, " ");  n++;
  208.         XtSetValues(statusLabel2, args, n);
  209.  
  210.         XtManageChild(cancelButton);
  211.  
  212.         break;
  213.     case STAT_TEMP_MESSAGE:
  214.         n=0;
  215.         if (host == (char *) NULL) {
  216.             XtSetArg(args[n], XtNlabel, " ");  n++;
  217.         } else {
  218.             sprintf (message, "%s, port %d", host, port);
  219.             XtSetArg(args[n], XtNlabel, message);  n++;
  220.         }
  221.         XtSetValues(statusLabel1, args, n);
  222.  
  223.         n=0;
  224.         XtSetArg(args[n], XtNlabel, TRANSIENT_MESSAGE);  n++;
  225.         XtSetValues(statusLabel2, args, n);
  226.  
  227.         XtUnmanageChild(cancelButton);
  228.  
  229.         (void) XtAppAddTimeOut(appcon, POPUP_SHOW_TIME,
  230.                     timeToRemoveProc, NULL);
  231.  
  232.         break;
  233.     }
  234.  
  235.  
  236.     if (!statusUp) {
  237.         positionAPopup(statusShell, topLevel, &placement);
  238.  
  239.         XtPopup (statusShell, XtGrabNonexclusive);
  240.  
  241.         statusUp = True;
  242.     }
  243.  
  244.     WaitForAllPendingEventsAndExpose(
  245.             XtDisplay(statusShell),
  246.             XtWindow(statusLabel1));
  247.  
  248.     } else { /* NO_STATUS_POPUP */
  249.  
  250.     type = thisType;
  251.     switch (type) {
  252.     case STAT_TEMP_MESSAGE:
  253.         changeStatusLabel (text, type);
  254.         (void) XtAppAddTimeOut(appcon, MSG_SHOW_TIME,
  255.                     timeToRemoveProc, NULL);
  256.         break;
  257.     /* STAT_CONNECT, STAT_ROOT, STAT_DIRECTORY, STAT_ASCII, STAT_BINARY */
  258.     /* and STAT_PROCESS */
  259.     default:
  260.         {
  261.         changeStatusLabel (text, type);
  262.         break;
  263.         }
  264.     }
  265.     cancelled = False;
  266.  
  267.     }  /* NO_STATUS_POPUP */
  268.  
  269.     return;
  270. }
  271.  
  272.  
  273. /* removeStatusPanel
  274.    Pop down the status panel. */
  275.  
  276. BOOLEAN
  277. removeStatusPanel()
  278. {
  279.  
  280.         type = STAT_USER;
  281.  
  282.     if (appResources->statusWindow) {    /* STATUS_POPUP */
  283.  
  284.     if (statusUp) {
  285.         XtPopdown(statusShell);
  286.         WaitForAllPendingEventsAndExpose(
  287.             XtDisplay(statusShell),
  288.             (Window) NULL);
  289.         statusUp = False;
  290.     }
  291.  
  292.     } else { /* NO_STATUS_POPUP */
  293.  
  294.     changeStatusLabel (DEFAULT_STATUS_MESSAGE, type);
  295.  
  296.     }  /* NO_STATUS_POPUP */
  297.  
  298.         return !cancelled;
  299. }
  300.  
  301.  
  302. /* updateStatusPanel
  303.    send update info to be displayed.  Return value Boolean indicates
  304.    whether to continue.  A cancel request, for example, returns False. */
  305.  
  306. BOOLEAN
  307. updateStatusPanel(value1, value2)
  308. int    value1, value2;
  309. {
  310.  
  311.     char    message[MESSAGE_STRING_LEN];
  312.  
  313.     if (appResources->statusWindow) {    /* STATUS_POPUP */
  314.  
  315.     Arg        args[10];
  316.     Cardinal    n;
  317.  
  318.     if (cancelled) return False;
  319.  
  320.     switch (type) {
  321.     case STAT_CONNECT:
  322.         if (value1 == 1) {
  323.             /* first, drain all events to see any cancel during
  324.                a connect. */
  325.  
  326.             if (statusUp) { 
  327.                 WaitForAllPendingEventsAndExpose(
  328.                     XtDisplay(statusShell),
  329.                     (Window) NULL );
  330.             }
  331.             if (cancelled) return False;
  332.  
  333.             n=0;
  334.             XtSetArg(args[n], XtNlabel, "(connected)");  n++;
  335.             XtSetValues(statusLabel2, args, n);
  336.             if (statusUp) { 
  337.                 WaitForAllPendingEventsAndExpose(
  338.                     XtDisplay(statusShell),
  339.                     XtWindow(statusLabel2) );
  340.             }
  341.         }
  342.  
  343.         break;
  344.     case STAT_ROOT:
  345.     case STAT_DIRECTORY:
  346.         sprintf (message, "%6d items received", value1);
  347.         n=0;
  348.         XtSetArg(args[n], XtNlabel, message);  n++;
  349.         XtSetValues(statusLabel1, args, n);
  350.         if (statusUp) { 
  351.             WaitForAllPendingEventsAndExpose(
  352.                 XtDisplay(statusShell),
  353.                 XtWindow(statusLabel1) );
  354.         }
  355.  
  356.         break;
  357.     case STAT_ASCII:
  358.         sprintf (message, "%6d lines received", value1);
  359.         n=0;
  360.         XtSetArg(args[n], XtNlabel, message);  n++;
  361.         XtSetValues(statusLabel1, args, n);
  362.         if (statusUp) { 
  363.             WaitForAllPendingEventsAndExpose(
  364.                 XtDisplay(statusShell),
  365.                 (Window) NULL);
  366.         }
  367.  
  368.         break;
  369.     case STAT_BINARY:
  370.         sprintf (message, "%6d characters received", value1);
  371.         n=0;
  372.         XtSetArg(args[n], XtNlabel, message);  n++;
  373.         XtSetValues(statusLabel1, args, n);
  374.         if (statusUp) { 
  375.             WaitForAllPendingEventsAndExpose(
  376.                 XtDisplay(statusShell),
  377.                 (Window) NULL);
  378.         }
  379.  
  380.         break;
  381.     case STAT_PROCESS:
  382.     case STAT_TEMP_MESSAGE:
  383.         break;
  384.     }
  385.  
  386.     } else { /* NO_STATUS_POPUP */
  387.  
  388.     switch (type) {
  389.     case STAT_ROOT:
  390.     case STAT_DIRECTORY:
  391.         sprintf (message, "%6d items received", value1);
  392.         changeStatusLabel (message, type);
  393.         break;
  394.     case STAT_ASCII:
  395.         sprintf (message, "%6d lines received", value1);
  396.         changeStatusLabel (message, type);
  397.         break;
  398.     case STAT_BINARY:
  399.         sprintf (message, "%6d characters received", value1);
  400.         changeStatusLabel (message, type);
  401.         break;
  402.     case STAT_PROCESS:
  403.     case STAT_TEMP_MESSAGE:
  404.         break;
  405.     }
  406.  
  407.     }  /* NO_STATUS_POPUP */
  408.  
  409.     return True;
  410. }
  411.  
  412.  
  413. /* makeStatusPanel
  414.    create the X panel to display status information */
  415.  
  416. void
  417. makeStatusPanel(top)
  418. Widget    top;
  419. {
  420.     Arg        args[10];
  421.     Cardinal    n;
  422.     Dimension    w, h;
  423.     Widget        statusForm;
  424.     Dimension    width, height, formWidth, labelWidth;
  425.     int        labelDistance;
  426.  
  427.     if (appResources->statusWindow) {    /* STATUS_POPUP */
  428.  
  429.     static XtActionsRec     statusActionsTable[] = {
  430.             { "statusCancel", (XtActionProc) statusCancelAction }
  431.                     };
  432.  
  433.  
  434.     topLevel = top;
  435.  
  436.  
  437.     /* create Status shell */
  438.  
  439.         n=0;
  440.         XtSetArg(args[n], XtNtitle, STATUS_SHELL_TITLE);  n++;
  441.     statusShell = XtCreatePopupShell("statusShell",
  442.                 transientShellWidgetClass,
  443.                 topLevel, args, n);
  444.  
  445.  
  446.     /* create Status main panel form */
  447.  
  448.         n=0;
  449.     statusForm  = XtCreateManagedWidget("statusForm",
  450.                 formWidgetClass,
  451.                 statusShell, args, n);
  452.  
  453.     /* create descriptive label */
  454.  
  455.         n=0;
  456.         XtSetArg(args[n], XtNjustify, XtJustifyCenter);  n++;
  457.     whatLabel = XtCreateManagedWidget("statusText",
  458.                 labelWidgetClass,
  459.                 statusForm, args, n);
  460.  
  461.         /* find a nice width */
  462.  
  463.         getTextSize(whatLabel, 50, 1, &width, &height);
  464.         n=0;
  465.         XtSetArg(args[n], XtNwidth, width);  n++;
  466.         XtSetValues(whatLabel, args, n);
  467.  
  468.  
  469.     /* create status label one */
  470.  
  471.         n=0;
  472.         XtSetArg(args[n], XtNfromVert, whatLabel);  n++;
  473.         XtSetArg(args[n], XtNjustify, XtJustifyCenter);  n++;
  474.         XtSetArg(args[n], XtNwidth, width);  n++;
  475.     statusLabel1 = XtCreateManagedWidget("statusLabel1",
  476.                 labelWidgetClass,
  477.                 statusForm, args, n);
  478.  
  479.     /* create status label two */
  480.  
  481.         n=0;
  482.         XtSetArg(args[n], XtNfromVert, statusLabel1);  n++;
  483.         XtSetArg(args[n], XtNjustify, XtJustifyCenter);  n++;
  484.         XtSetArg(args[n], XtNwidth, width);  n++;
  485.     statusLabel2 = XtCreateManagedWidget("statusLabel2",
  486.                 labelWidgetClass,
  487.                 statusForm, args, n);
  488.  
  489.     /* find the form width */
  490.  
  491.     n=0;
  492.     XtSetArg(args[n], XtNwidth, &labelWidth);  n++;
  493.     XtSetArg(args[n], XtNhorizDistance, &labelDistance);  n++;
  494.     XtGetValues(whatLabel, args, n);
  495.  
  496.     /* create CANCEL button */
  497.  
  498.         n=0;
  499.         XtSetArg(args[n], XtNfromVert, statusLabel2);  n++;
  500.     cancelButton = XtCreateManagedWidget("statusCancel",
  501.                 commandWidgetClass,
  502.                 statusForm, args, n);
  503.  
  504.         /* center the button on the form */
  505.  
  506.         n=0;
  507.         XtSetArg(args[n], XtNwidth, &width);  n++;
  508.         XtGetValues(cancelButton, args, n);
  509.  
  510.         n=0;
  511.         XtSetArg(args[n], XtNhorizDistance,
  512.             ((labelDistance+(int)labelWidth)-(int)width)/2);  n++;
  513.         XtSetValues(cancelButton, args, n);
  514.  
  515.     XtAddCallback(cancelButton, XtNcallback, cancelProc, NULL);
  516.  
  517.  
  518.     XtAppAddActions(appcon, statusActionsTable,
  519.             XtNumber(statusActionsTable));
  520.  
  521.  
  522.         /* for ICCCM window manager protocol complience */
  523.  
  524.         XtOverrideTranslations (statusShell,
  525.             XtParseTranslationTable ("<Message>WM_PROTOCOLS: statusCancel()"));
  526.         XtRealizeWidget(statusShell);
  527.         (void) XSetWMProtocols (XtDisplay(statusShell), XtWindow(statusShell),
  528.                                     &wmDeleteAtom, 1);
  529.  
  530.     /* find the popup placement for this shell */
  531.  
  532.     {
  533.     popupPosResources *resourcePlacement;
  534.  
  535.     resourcePlacement = getPopupPosResources(
  536.                 THIS_POPUP_NAME, POPUP_POS_CLASS, &placement);
  537.     bcopy( (char *) resourcePlacement, (char *) &placement,
  538.                 sizeof(popupPosResources) );
  539.     }
  540.  
  541.     /* set status shell's minimum size to initial size */
  542.  
  543.     {
  544.         Dimension    w, h;
  545.  
  546.         n = 0;
  547.         XtSetArg(args[n], XtNwidth, &w);  n++;
  548.         XtSetArg(args[n], XtNheight, &h);  n++;
  549.         XtGetValues(statusForm, args, n);
  550.  
  551.         n = 0;
  552.         XtSetArg(args[n], XtNminWidth, w);  n++;
  553.         XtSetArg(args[n], XtNminHeight, h);  n++;
  554.         XtSetValues (statusShell, args, n);
  555.     }
  556.  
  557.     statusPanelCreated = True;
  558.     } else { /* NO_STATUS_POPUP */
  559.         type = STAT_USER;
  560.     }  /* NO_STATUS_POPUP */
  561.         changeStatusLabel (DEFAULT_STATUS_MESSAGE, STAT_USER);
  562. }
  563.